package com.producer.死信队列;

import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

@Component
public class DeadQueueConfig {
    /**
     * 主队列交换机名称
     */
    public static final String MAIN_EXCHANGE_NAME = "main.direct.exchange";

    /**
     * 首先创建主队列交换机
     */
    @Bean("mainDirectExchange")
    public DirectExchange createMainExchange(@Qualifier("rabbitAdmin") RabbitAdmin rabbitAdmin){
        //这里只是声明交换机，不存在也不会报错，也不会创建
        DirectExchange mainDirectExchange = new DirectExchange(MAIN_EXCHANGE_NAME,false,false);
        //如果交换机不存在会创建
        rabbitAdmin.declareExchange(mainDirectExchange);
        return mainDirectExchange;
    }

    /**
     * 主队列交换机名称
     */
    public static final String DEAD_EXCHANGE_NAME = "dead.direct.exchange";
    /**
     * 然后创建死信队列交换机
     */
    @Bean("deadExchange")
    public DirectExchange createDeadExchange(@Qualifier("rabbitAdmin") RabbitAdmin rabbitAdmin){
        DirectExchange deadDirectExchange = new DirectExchange(DEAD_EXCHANGE_NAME,false,false);
        rabbitAdmin.declareExchange(deadDirectExchange);
        return deadDirectExchange;
    }

    /**
     * 死信队列名称
     */
    public static final String DEAD_QUEUE_NAME = "dead.queue";
    /**
     * 死信队列的消息路由词
     */
    public static final String DEAD_QUEUE_ROUTINGKEY = "dead.queue.routingkey";
    /**
     * 创建死信队列并绑定死信队列交换机
     * @param rabbitAdmin
     * @param exchange
     * @return
     */
    @Bean("deadQueue")
    public Queue createDeadQueue(@Qualifier("rabbitAdmin") RabbitAdmin rabbitAdmin, @Qualifier("deadExchange") DirectExchange exchange){
        Queue deadQueue = new Queue(DEAD_QUEUE_NAME,false,false,false);
        rabbitAdmin.declareQueue(deadQueue);
        rabbitAdmin.declareBinding(BindingBuilder.bind(deadQueue).to(exchange).with(DEAD_QUEUE_ROUTINGKEY));
        return deadQueue;
    }

    /**
     * 主队列名称
     */
    public static final String MAIN_QUEUE_NAME = "main.queue";
    /**
     * 主队列消息路由关键词
     */
    public static final String MAIN_QUEUE_ROUTINGKEY = "main.queue.routingkey";
    /**
     * 创建主队列并和主队列交换机绑定
     * x-single-active-consumer:表示配置队列只允许单个消费者消费消息，其它消费者将被阻塞，直到当前消费者停止消费或者断开
     * x-dead-letter-exchange:设置队列种的死信消息发送到的交换机的名称，当消息成为死信消息时，将会被转发到指定的交换机
     * x-dead-letter-routing-key:设置私信消息转发到死信交换机时的路由键
     * x-max-length:设置队列的最大长度，当队列种的消息数量达到最大限度后，新消息将无法入队列
     * x-message-ttl:队列消息过期时间，单位毫秒
     * @param rabbitAdmin
     * @param exchange
     * @return
     */
    @Bean("mainQueue")
    public Queue createMainQueue(@Qualifier("rabbitAdmin") RabbitAdmin rabbitAdmin, @Qualifier("mainDirectExchange") DirectExchange exchange){
        Map<String, Object> arguments = new HashMap<String, Object>();
        arguments.put("x-dead-letter-exchange", DEAD_EXCHANGE_NAME);
        arguments.put("x-dead-letter-routing-key", DEAD_QUEUE_ROUTINGKEY);
        Queue mainQueue = new Queue(MAIN_QUEUE_NAME,false,false,false,arguments);
        //如果队列不存在会创建
        rabbitAdmin.declareQueue(mainQueue);
        rabbitAdmin.declareBinding(BindingBuilder.bind(mainQueue).to(exchange).with(MAIN_QUEUE_ROUTINGKEY));
        return mainQueue;
    }
}
